package ace.tool.generate.code.impl.resolver.ui.resolver;

import ace.tool.generate.code.impl.resolver.ui.model.dto.UiClassFileInfo;
import java.util.HashMap;
import java.util.Map;
import lombok.Builder;
import org.apache.commons.text.StringSubstitutor;
import org.apache.commons.text.WordUtils;

/**
 * @author caspar
 * @date 2023/11/17 10:34
 */
@Builder
public class UiClassFileInfoResolver {
  /**
   * 源文件根目录
   */
  private final String sourceCodeRootDir;

  /**
   * 类名
   */
  private final String className;

  /**
   * 类名后缀
   */
  private final String classNameSuffix;

  /**
   * 类包相对路径前缀
   */
  private final String classPackagePrefix;

  /**
   * 类包根路径
   */
  private final String rootPackageFullName;

  /**
   * 文件后缀名
   */
  private final String fileNameSuffix;

  public UiClassFileInfo resolve() {
    return UiClassFileInfo.builder()
        .classFileFullName(this.getClassFileFullName())
        .uncapitalizeClassFileFullName(this.getUncapitalizeClassFileFullName())
        .classFullName(this.getClassFullName())
        .uncapitalizeClassFullName(this.getUncapitalizeClassFullName())
        .className(this.getClassName())
        .uncapitalizeClassName(this.getUncapitalizeClassName())
        .classPackageFullName(this.getClassPackageFullName())
        .build();
  }

  public String getClassFileFullName() {
    return this.getClassFileFullName0(false);
  }

  public String getUncapitalizeClassFileFullName() {
    Map<String, String> data = new HashMap<>();
    data.put("sourceCodeRootDir", this.sourceCodeRootDir);
    data.put("classFileFullName", this.getClassFullNamePath(true));
    data.put("fileNameSuffix", this.fileNameSuffix);
    String result =
        StringSubstitutor.replace(
            "${sourceCodeRootDir}${classFileFullName}${fileNameSuffix}", data);
    return result;
  }

  public String getClassPackageFullName() {
    Map<String, String> data = new HashMap<>();
    data.put("rootPackageFullName", this.rootPackageFullName);
    data.put("classPackagePrefix", this.classPackagePrefix);
    return StringSubstitutor.replace("${rootPackageFullName}${classPackagePrefix}", data);
  }

  public String getClassFullName() {
    return "@" + this.getClassFullNamePath();
  }

  public String getUncapitalizeClassFullName() {
    return "@" + this.getClassFullNamePath(true);
  }

  public String getClassName() {
    Map<String, String> data = new HashMap<>();
    data.put("classNameSuffix", this.classNameSuffix);
    data.put("className", this.className);
    return StringSubstitutor.replace("${className}${classNameSuffix}", data);
  }

  public String getUncapitalizeClassName() {
    return WordUtils.uncapitalize(this.getClassName());
  }

  public String getClassFileFullName0(boolean uncapitalizeClassNameFlag) {
    Map<String, String> data = new HashMap<>();
    data.put("sourceCodeRootDir", this.sourceCodeRootDir);
    data.put("classFileFullName", this.getClassFullNamePath(uncapitalizeClassNameFlag));
    data.put("fileNameSuffix", this.fileNameSuffix);
    String result =
        StringSubstitutor.replace(
            "${sourceCodeRootDir}${classFileFullName}${fileNameSuffix}", data);
    return result;
  }

  private String getClassFullNamePath() {
    return this.getClassFullNamePath(false);
  }

  private String getClassFullNamePath(boolean uncapitalizeClassNameFlag) {
    String className =
        uncapitalizeClassNameFlag
            ? WordUtils.uncapitalize(this.getClassName())
            : this.getClassName();
    Map<String, String> data = new HashMap<>();
    data.put("packageFullName", this.getClassPackageFullName());
    data.put("className", className);
    String result = StringSubstitutor.replace("${packageFullName}/${className}", data);
    return result;
  }
}
